'''
useage:
result = get_bajiao(image, results)
    image：cv2对象，shape一般为（480，480，3）
    results：3_pad列表（八角形pad）[[loc_1, loc_2, loc_3, loc_4], [loc_1, loc_2, loc_3, loc_4], ...]

    result：返回值列表[(area,[loc_1, loc_2, loc_3, loc_4, loc_7, loc_8, loc_5, loc_6]), (area,[loc_1, loc_2, loc_3, loc_4, loc_7, loc_8, loc_5, loc_6]), ...]
'''

import cv2
import numpy as np

# 0: 1_pad, 1: 2_pad, 2: 3_pad, 3: 4_nmpad, 4: 5_pollution

# paragrams
move_length_per = 1/3 # 测量矩阵滑动距离，宽高比
limit_distance = 55 # 边缘过滤距离
maxtrix_size = 4 # 测量矩阵大小
limit_value_per = 0.06 # 第一个接近灰度最大值的值，值越大，框越往外，值越小，框越往内


# 通过灰度值列表计算黑边的长度是多少
def cal_length_by_ave_gray_list(ave_gray_list):
    max_ave_gray = max(ave_gray_list)
    limit_value = max_ave_gray*limit_value_per
    for x in range(len(ave_gray_list)):
        if abs(ave_gray_list[x]-max_ave_gray) < limit_value:
            return x


def get_bajiao(image, results):
    if len(image.shape) == 3:
        gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    ori_shape = gray_image.shape # 原始图像大小
    all_ave_gray_list = []
    for index in range(len(results)):
        bbox = results[index]
        
        bbox = [x if x >= 0 else 0 for x in bbox]
        # 得到x，y坐标
        loc_x_min = int(bbox[1])
        loc_x_max = int(bbox[3])
        loc_y_min = int(bbox[0])
        loc_y_max = int(bbox[2])
        # bbox宽、高
        bbox_height = abs(loc_x_max - loc_x_min)
        bbox_width = abs(loc_y_max - loc_y_min)
        # 边缘pad过滤，如果pad的整体在limit_distance内部，则跳过
        # if loc_x_max < limit_distance or loc_y_max < limit_distance or (ori_shape[0]-loc_x_min) < limit_distance or (ori_shape[1]-loc_y_min) < limit_distance:
        #     continue
        # bbox灰度图片
        bbox_img = gray_image[loc_x_min:loc_x_max, loc_y_min:loc_y_max]
        # 点在widht和height上移动的距离，迭代次数
        move_width = int(move_length_per * bbox_width)
        move_height = int(move_length_per * bbox_height)
        # 左 上 -> 右
        ave_gray_list_lur = []
        for index in range(move_width):
            move_mat_3x3 = bbox_img[:maxtrix_size, index:maxtrix_size+index]
            ave_gray_value = int(move_mat_3x3.mean())
            ave_gray_list_lur.append(ave_gray_value)
        # 左 上 -> 下
        ave_gray_list_lud = []
        for index in range(move_height):
            move_mat_3x3 = bbox_img[index:maxtrix_size+index, :maxtrix_size]
            ave_gray_value = int(move_mat_3x3.mean())
            ave_gray_list_lud.append(ave_gray_value)
        # 右 上 -> 左
        ave_gray_list_rul = []
        for index in range(move_width):
            if index == 0:
                move_mat_3x3 = bbox_img[-maxtrix_size-index:, :maxtrix_size]
            else:
                move_mat_3x3 = bbox_img[:maxtrix_size, -maxtrix_size-index:-index]
            ave_gray_value = int(move_mat_3x3.mean())
            ave_gray_list_rul.append(ave_gray_value)
        # 右 上 -> 下
        ave_gray_list_rud = []
        for index in range(move_height):
            move_mat_3x3 = bbox_img[index:maxtrix_size+index, -maxtrix_size:]
            ave_gray_value = int(move_mat_3x3.mean())
            ave_gray_list_rud.append(ave_gray_value)
        # 右 下 -> 左
        ave_gray_list_rdl = []
        for index in range(move_width):
            if index == 0:
                move_mat_3x3 = bbox_img[-maxtrix_size-index:, :maxtrix_size]
            else:
                move_mat_3x3 = bbox_img[-maxtrix_size:, -maxtrix_size-index:-index]
            ave_gray_value = int(move_mat_3x3.mean())
            ave_gray_list_rdl.append(ave_gray_value)
        # 右 下 -> 上
        ave_gray_list_rdu = []
        for index in range(move_height):
            if index == 0:
                move_mat_3x3 = bbox_img[-maxtrix_size-index:, :maxtrix_size]
            else:
                move_mat_3x3 = bbox_img[-maxtrix_size-index:-index, -maxtrix_size:]
            ave_gray_value = int(move_mat_3x3.mean())
            ave_gray_list_rdu.append(ave_gray_value)
        # 左 下 -> 右
        ave_gray_list_ldr = []
        for index in range(move_width):
            move_mat_3x3 = bbox_img[-maxtrix_size:, index:maxtrix_size+index]
            ave_gray_value = int(move_mat_3x3.mean())
            ave_gray_list_ldr.append(ave_gray_value)
        # 左 下 -> 上
        ave_gray_list_ldu = []
        for index in range(move_height):
            if index == 0:
                move_mat_3x3 = bbox_img[-maxtrix_size-index:, :maxtrix_size]
            else:
                move_mat_3x3 = bbox_img[-maxtrix_size-index:-index, :maxtrix_size]
            ave_gray_value = int(move_mat_3x3.mean())
            ave_gray_list_ldu.append(ave_gray_value)
        
        all_ave_gray_list.append(ave_gray_list_lur)
        all_ave_gray_list.append(ave_gray_list_lud)
        all_ave_gray_list.append(ave_gray_list_rul)
        all_ave_gray_list.append(ave_gray_list_rud)
        all_ave_gray_list.append(ave_gray_list_rdl)
        all_ave_gray_list.append(ave_gray_list_rdu)
        all_ave_gray_list.append(ave_gray_list_ldr)
        all_ave_gray_list.append(ave_gray_list_ldu)

    # 把所有曲线合并成一条曲线
    shortest_list_len = min(len(sublist) for sublist in all_ave_gray_list)
    new_all_ave_gray_list = [x[:shortest_list_len] for x in all_ave_gray_list]
    sum_all_ave_gray_list = np.sum(new_all_ave_gray_list, axis=0)
    # 每个顶点缩进的长度
    length = cal_length_by_ave_gray_list(sum_all_ave_gray_list)
    result = []
    for bbox in results:
        loc_x_min = int(bbox[1])
        loc_x_max = int(bbox[3])
        loc_y_min = int(bbox[0])
        loc_y_max = int(bbox[2])
        # bbox宽、高
        bbox_height = abs(loc_x_max - loc_x_min)
        bbox_width = abs(loc_y_max - loc_y_min)
        # 原来的面积
        area = bbox_height * bbox_width
        # 边缘pad过滤，如果pad的整体在limit_distance内部，则跳过
        loc_1 = [bbox[0]+length, bbox[1]]
        loc_2 = [bbox[0], bbox[1]+length]
        loc_3 = [bbox[0], bbox[3]-length]
        loc_4 = [bbox[0]+length, bbox[3]]
        loc_5 = [bbox[2], bbox[1]+length]
        loc_6 = [bbox[2]-length, bbox[1]]
        loc_7 = [bbox[2]-length, bbox[3]]
        loc_8 = [bbox[2], bbox[3]-length]
        # 新的面积
        new_area = area - 2*length*length
        result.append((new_area, [loc_1, loc_2, loc_3, loc_4, loc_7, loc_8, loc_5, loc_6]))
    return result
